package com.wms.service;

import com.mes.utils.SendMessageUtil;
import com.wms.entity.StorageInOut;
import com.mes.entity.User;
import com.yy.base.common.dao.Dao;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 收货确认
 * @author ZT
 */
@Service
@SuppressWarnings("unchecked")
public class StockConfirmService {
	@Autowired
	private Dao dao;
	
	@Autowired
	private StorageDetailService detailService;
	/**
	 * 验证是否有出库单号
	 * (此处后期应该加不同状态的提醒)
	 */
	public Map<String, Object> getOutCodebyInfo(String code) {
		// 其他出库单号
		String sql = "select Wms_Material_List_Head_ID, Status from Wms_Material_List_Head where code =?";
		Map<String, Object> orderInfo = dao.queryUnique(sql, code);
		if (orderInfo != null) {
			if ("OK".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该出库单已完成出库");
			} else if ("CLOSE".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该出库单已关闭");
			}
			return orderInfo;
		}
		// 正式领料单出库单号
		sql = "select Wms_Put_M_Formal_id, Status from Wms_Put_M_Formal where code =?";
		orderInfo = dao.queryUnique(sql, code);
		if (orderInfo != null) {
			if ("OK".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该领料单已完成出库！");
			}
			return orderInfo;
		}
		//呼叫投料单号
		sql = "select wms_call_put_m_id,code from Wms_Call_Put_M where code =?";
		orderInfo = dao.queryUnique(sql, code);
		if (orderInfo != null) {
			if ("CLOSE".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该领料单已完成出库！");
			}
			return orderInfo;
		}
		
		// 退货出库单号
		sql = "Select Wms_Return_Goods_id, Status from Wms_Return_Goods where code=?";
		orderInfo = dao.queryUnique(sql, code);
		if (orderInfo != null) {
			if ("CREATE".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该采购退货单未审核");
			} else if ("NO_PASS".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该采购退货单审核未通过");
			} else if ("OK".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该采购退货单已完成出库");
			} else if ("CLOSE".equals(orderInfo.get("STATUS"))) {
				throw new RuntimeException("该采购退货单审核已关闭");
			}
		}
		return orderInfo;
	}

	/**
	 * 根据单据编码查询单据出库列表
	 * @param code
	 * @return
	 */
	public List<Map<String, Object>> getOrderOutList(String code, String mxId) {
		List<Map<String, Object>> list = null;
		//其他出库查询sql
		String sql = "select sb.m_product_id,	" +
					  "		mp.name	pname,	" +
					  "		(select name from WMS_QUALITY_GRADE wqg where wqg.wms_quality_grade_id = sb.wms_quality_grade_id) gname,"+
					  "		mp.product_spec	spec,	"+
					  "     abs(io.qty) qty,	" +
					  "		lmx.qty-nvl(lmx.qty_out,0) xuQty,	" +
					  "		io.M_Warehouse_ID,	"+
					  "     sb.batch_no,	"+
					  "     lmx.Wms_Material_List_L_Mx_Id mxId,	"+
					  "     l.Wms_Material_List_Head_Id orderId,	"+
					  "     io.Wms_Storage_In_Out_Id,	"+
					  "     (select wms_get_storage_szie(io.M_Warehouse_ID,	"+
					  "                                  sb.M_Product_ID,	"+
					  "                                  sb.Emes_Vendor_ID,	"+
					  "                                  '',	"+
					  "                                  sb.batch_no,	"+
					  "                                  lm.use_status)	"+
					  "        from dual) storageQty,	"+
					  "     (select value	"+
					  "        from M_Locator lo	"+
					  "       where lo.M_Locator_Id = io.M_Locator_Id) locator,	"+
					  "     'Wms_Material_List_L_Mx' as type	"+
					  "from Wms_Storage_Batch      sb,	"+
					  "     Wms_Storage_In_Out     io,	"+
					  "     Wms_Material_List_L_Mx lmx,	"+
					  "     Wms_Material_List_Head l," +
					  "		Wms_Material_List_Mx lm,	"+
					  "     m_product mp		"+
					  "where sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id	"+
					  " and io.status = 'LOCKED'	"+
					  " and io.data_id = lmx.Wms_Material_List_L_Mx_Id	"+
					  " and mp.m_product_id = sb.m_product_id	"+
					  " and lmx.Wms_Material_List_Head_Id = l.Wms_Material_List_Head_Id	" +
					  "	and lmx.wms_material_list_mx_id = lm.wms_material_list_mx_id	"+
					  " and l.code = ?";
					if (StringUtils.isNotEmpty(mxId)) {
						sql += " and lmx.Wms_Material_List_L_Mx_Id = '"+mxId+"'";
					}
		list = dao.query(sql, code);
		//正式领料单查询sql
		if (list == null || list.isEmpty()) {
			sql = "select mh.m_product_id,	"+
				"	       mp.name Pname,	" +
				"		   (select name from WMS_QUALITY_GRADE wqg where wqg.wms_quality_grade_id = sb.wms_quality_grade_id) gname,"+
				"	       mp.product_spec spec,	"+
				"	       abs(io.qty) qty,	" +
				"		   mh.qty-nvl(mh.act_qty,0) xuQty,	"+
				"	       sb.batch_no,	"+
				"	       mh.Wms_Put_M_Formal_Hz_Id mxId,	"+
				"	       mf.Wms_Put_M_Formal_Id orderId,	"+
				"	       io.Wms_Storage_In_Out_Id," +
				"			io.M_Warehouse_ID,	"+
				"	       (select wms_get_storage_szie(io.M_Warehouse_ID,	"+
				"	                                    sb.M_Product_ID,	"+
				"	                                    sb.Emes_Vendor_ID,	"+
				"	                                    '',	"+
				"	                                    sb.batch_no,	"+
				"	                                    '')	"+
				"	          from dual) storageQty,	"+
				"	       (select value	"+
				"	          from M_Locator lo	"+
				"	         where lo.M_Locator_Id = io.M_Locator_Id) locator,	"+
				"	       'Wms_Put_M_Formal_Hz' as type	"+
				"	  from Wms_Storage_Batch   sb,	"+
				"	       Wms_Storage_In_Out  io,	"+
				"	       Wms_Put_M_Formal_Hz mh,	"+
				"	       Wms_Put_M_Formal    mf,	"+
				"	       m_product mp	"+
				"	 where sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id	"+
				"	   and io.data_id = mh.Wms_Put_M_Formal_Hz_Id	"+
				"	   and mh.m_product_id = mp.m_product_id	"+
				"	   and io.status = 'LOCKED'	"+
				"	   and mh.Wms_Put_M_Formal_Id = mf.Wms_Put_M_Formal_Id	"+
				"	   and mf.code = ?";
			if (StringUtils.isNotEmpty(mxId)) {
				sql += " and mh.Wms_Put_M_Formal_Hz_Id = '"+mxId+"'";
			}
			list = dao.query(sql, code);
		}
		//采购退货查询sql
		if (list == null || list.isEmpty()) {
			sql = "select rgm.m_product_id,		"+
				"	       mp.name	pname,		" +
				"		   (select name from WMS_QUALITY_GRADE wqg where wqg.wms_quality_grade_id = sb.wms_quality_grade_id) gname,"+
				"	       mp.product_spec spec,		"+
				"	       abs(io.qty) qty,		" +
				"		   rgm.qty-nvl(rgm.qty_out,0) xuQty, "+
				"	       sb.batch_no,	" +
				"			io.M_Warehouse_ID,	"+
				"	       rgm.Wms_Return_Goods_Mx_Id mxId,		"+
				"	       rg.Wms_Return_Goods_Id orderId,		"+
				"	       io.Wms_Storage_In_Out_Id,		"+
				"	       (select wms_get_storage_szie(io.M_Warehouse_ID,		"+
				"	                                    sb.M_Product_ID,		"+
				"	                                    sb.Emes_Vendor_ID,		"+
				"	                                    '',		"+
				"	                                    sb.batch_no,		"+
				"	                                    '')		"+
				"	        from dual) storageQty,		"+
				"	       (select value		"+
				"	          from M_Locator lo		"+
				"	         where lo.M_Locator_Id = io.M_Locator_Id) locator,		"+
				"	       'Wms_Return_Goods_Mx' as type,		"+
				"	       rg.status		"+
				"	  from Wms_Storage_Batch   sb,		"+
				"	       Wms_Storage_In_Out  io,		"+
				"	       Wms_Return_Goods_Mx rgm,		"+
				"	       Wms_Return_Goods    rg,		"+
				"	       m_product    mp		"+
				"	 where sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id		"+
				"	   and io.data_id = rgm.Wms_Return_Goods_Mx_Id		"+
				"	   and mp.m_product_id = rgm.m_product_id		"+
				"	   and io.status = 'LOCKED'		"+
				"	   and rgm.Wms_Return_Goods_Id = rg.Wms_Return_Goods_Id		"+
				"	   and rg.code = ?";
			if (StringUtils.isNotEmpty(mxId)) {
				sql += " and rgm.Wms_Return_Goods_Mx_Id = '"+mxId+"'";
			}
			list = dao.query(sql, code);
		}
		
		return list;
	}
	/**
	 * 出库单确认出库，修改锁定状态
	 */
	public String outStorageConfirm(String ckd, List<Map<String, Object>> list, String mxId, double qtys, double xuQty, String locator, String batchNo, User user) {
		String qtyOutName = "qty_Out";
		if ("Wms_Put_M_Formal_Hz".equalsIgnoreCase((String)list.get(0).get("TYPE"))) {
			qtyOutName = "ACT_QTY";
		}
		
		double qty = 0;
		double lockQty = 0;
		for (Map<String, Object> map : list) {
			qty = qtys;
			lockQty = Math.abs(Double.parseDouble(map.get("QTY").toString()));
			
			if (qty < 0) {
				return map.get("M_PRODUCT_ID") + "批次" + map.get("BATCH_NO") + "出库数量不能为0或负数！";
			}
			if (qty > lockQty) {
				return map.get("M_PRODUCT_ID") + "批次" + map.get("BATCH_NO") + "不能多于需求数量：" + lockQty;
			}
			if (qty == 0) {
				//当发货数量为0，则将此出库记录设置为取消
				dao.executeSql("update WMS_STORAGE_IN_OUT set status = 'CANCEL', updated = now() where WMS_STORAGE_IN_OUT_ID = ?", map.get("WMS_STORAGE_IN_OUT_ID"));
			} else {
				//将状态修改为完成
//				dao.executeSql(sql, -qty, map.get("WMS_STORAGE_IN_OUT_ID"));
				// 当需求数量和实际出库数量一致时  直接修改锁定数量为当前批次
				if (xuQty < qtys) {
					throw new RuntimeException("实际数量大于需求数量");
				}else if (xuQty == qtys) {
					detailService.updateLockStorageBatchOk(mxId,locator,batchNo);
				}else {
					//当需求数量大于出库数量时 需要更改锁定数量      相同批次则不需要更改
					List<Map<String, Object>> detailList = detailService.findStorageInOut((String)map.get("WMS_STORAGE_IN_OUT_ID"));
					StorageInOut inStorage = new StorageInOut();
					String id = UUID.randomUUID().toString().replaceAll("-","");
					inStorage.setId(id);
					inStorage.setWarehouseId((String)detailList.get(0).get("M_WAREHOUSE_ID"));
					inStorage.setProductId((String)detailList.get(0).get("M_PRODUCT_ID"));
					inStorage.setQty((xuQty-qtys)*-1);
					inStorage.setUomId((String)detailList.get(0).get("C_UOM_ID"));
					inStorage.setStatus("LOCKED");
					inStorage.setDescription("");
					inStorage.setDataId(mxId);
					inStorage.setOptCode((String)detailList.get(0).get("OPT_CODE"));
					inStorage.setOptMode((String)detailList.get(0).get("OPT_MODE"));
					inStorage.setMainType((String)detailList.get(0).get("MAIN_TYPE"));
					inStorage.setSubType((String)detailList.get(0).get("SUB_TYPE"));
					inStorage.setSaleType((String)detailList.get(0).get("ORG_TYPE"));
					if (!batchNo.equals(list.get(0).get("BATCH_NO"))) {
						//批次和默认批次不一致时修改批次ID
						Map<String, Object> mapBatch = detailService.getStorageBatchWarehouseInfo(batchNo, (String)list.get(0).get("M_WAREHOUSE_ID"));
						inStorage.setStorageBatchId((String)mapBatch.get("WMS_STORAGE_BATCH_ID"));
						inStorage.setLocatorId((String)mapBatch.get("M_LOCATOR_ID"));
					}else {
						inStorage.setStorageBatchId((String)detailList.get(0).get("WMS_STORAGE_BATCH_ID"));
						inStorage.setLocatorId((String)detailList.get(0).get("M_LOCATOR_ID"));
					}
					//另外需要增加一条出库记录
					detailService.updateLockStorageBatchOk((String)map.get("WMS_STORAGE_IN_OUT_ID"), -qty);
					detailService.addOutStorage(inStorage, user);
				}
			}
			
			dao.executeSql("update " + map.get("TYPE") + " set " + qtyOutName + " = NVL(" + qtyOutName + ", 0) + ? where " + 
					map.get("TYPE") + "_Id = ?", qty, map.get("MXID"));
			
			//将出库数量修改到领料单明细的已生产正式数量（未发料的数量还可以继续生成领料单重新领料）
			if ("Wms_Put_M_Formal_Hz".equalsIgnoreCase((String)map.get("TYPE"))) {
				dao.executeSql("update Wms_Put_Material_Hz mh " +
						"set Qty_Out = nvl(Qty_Out, 0) + ? " +
						"where exists (" +
						"	select 1 from Wms_Put_M_Formal_Hz fh " +
						"	 where fh.Wms_Put_Material_Hz_Id = mh.Wms_Put_Material_Hz_Id " +
						"  	   and fh.Wms_Put_M_Formal_Hz_Id = ?)", qty,  map.get("MXID"));
				
				
				//修改正是领料单的备料人，领料时间
				dao.executeSql("update Wms_Put_M_Formal set Admin_User = ?, Take_Date = now() " +
						"where Admin_User is null and Wms_Put_M_Formal_Id = ?", user.getId(), map.get("ORDERID"));
				
				//回写到MES的领料申请单中
				if ("scly".equalsIgnoreCase((String)map.get("OUT_TYPE"))) {
//					String code = (String) map.get("CODE");
					//取消回写，mes自动同步
//					if ("C4".equals(code.substring(3, 5))) {
//						String updateMesSql = "update MES.EMESO_MANU_OM_STORAGE set qty = (qty+?) where M_PRODUCT_ID = ? and ad_org_id = '4BAD2EB3B9B844FAABCDDD744E529F55'";
//						dao.executeSql(updateMesSql, qty,map.get("M_PRODUCT_ID"));
//					} else {
//						String updateMesSql = "update MES.EMESO_MANU_OM_STORAGE set qty = (qty+?) where M_PRODUCT_ID = ? and ad_org_id = '7B441EB01848477687A8ADE94F1F5F2A'";
//						dao.executeSql(updateMesSql, qty,map.get("M_PRODUCT_ID"));
//					}
				}
			//其他出库修改出库数量，状态
			} else if ("Wms_Material_List_L_Mx".equalsIgnoreCase((String)map.get("TYPE"))) {
				dao.executeSql("update Wms_Material_List_Mx mx set Qty_Out = nvl(Qty_Out, 0) - ? " +
						"where mx.Wms_Material_List_Mx_Id = ?", (lockQty - qty), map.get("MXID"));
				
				//修改正是领料单的备料人，备料时间
				dao.executeSql("update Wms_Material_List_Head set Prepare_User = ?, Prepare_Date = now(), status = 'YBL' " +
						"where Prepare_User is null and Wms_Material_List_Head_Id = ?", user.getId(), map.get("ORDERID"));
			}
		}
		updateOrderStatus();
		String mesSql = "select status from Wms_Return_Goods where code = ? and status = 'OK'";
		if (dao.query(mesSql, ckd).size() > 0) {
			String msgTest = "采购退货单号："+ckd+"已出库，请及时查验";
			SendMessageUtil.sendMessage("CGTHXXTS", msgTest, msgTest);
		}
		return null;
	}
	
	// 调用出库单的状态(可以将所有单据的更新都放到这个存储过程)
	public void updateOrderStatus() {
		dao.callSql("{ call Wms_Change_Order_Status() }");
	}
}
